package com.my.blog.myblog.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.alibaba.druid.support.json.JSONUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.my.blog.annotation.AccessLimit;
import com.my.blog.annotation.SystemLog;
import com.my.blog.myblog.entity.Blog;
import com.my.blog.myblog.entity.Blogtype;
import com.my.blog.myblog.service.BlogService;
import com.my.blog.myblog.service.BlogTypeService;
import com.my.blog.utils.BlogIdSafeUtils;
import com.my.blog.utils.ConstantUtil;
import com.my.blog.utils.ResultBean;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/***
 *
 * @Auther: MuYun
 * @Date: 2021/8/19 16:33
 * @Description： 博客的controller
 *
 */
@RestController
public class BlogController {

    @Resource
    private BlogService blogService;

    @Resource
    private BlogTypeService blogTypeService;

    @GetMapping("/selectLikeBlogListByPage")
    @AccessLimit(second = 5,maxCount = 15)
    public ResultBean<IPage<Blog>> selectLikeBlogListByPage(Blog blog,
                                                            @RequestParam(value = "sort",defaultValue = "addTime")String sort,
                                                            @RequestParam(value = "page",defaultValue = "1")Integer page,
                                                            @RequestParam(value = "pageSize",defaultValue = "10")Integer pageSize){

        QueryWrapper<Blog> wrapper = designWrapper(blog, sort);
        Page<Blog> blogPage = blogService.page(new Page<>(page, pageSize), wrapper);
        ResultBean<IPage<Blog>> resultBean=new ResultBean<>();
        if(ObjectUtil.isNotEmpty(blogPage.getRecords())){
            resultBean.setData(blogPage);
        }else {
            resultBean.setCode(ResultBean.FAIL);
        }
        return resultBean;
    }

    /**
     * 根据博客id获取具体博客
     * @param id
     * @return
     */
    @GetMapping("/find/{id}.html")
    @SystemLog(description = ConstantUtil.BLOG_SELECT,userType = ConstantUtil.USERTYPE_USER)
    public ModelAndView selectBlogById(@PathVariable Integer id){
        ModelAndView mv=new ModelAndView();
        if(id==null||id<=0){
            mv.setViewName("error/404");
        }else {
            Blog blog = blogService.getById(BlogIdSafeUtils.blogIdToSafe(id));
            if(ObjectUtil.isEmpty(blog)){
                mv.setViewName("error/404");
            }else {
                //点击量+1
                blog.setClickNum(blog.getClickNum()+1);
                blogService.updateById(blog);

                //返回界面
                mv.setViewName("page/info");
                mv.addObject(blog);
            }
        }
        return mv;
    }


    @GetMapping("/selectNextBlog")
    public ResultBean<Blog> selectNextBlog(@RequestParam(value = "id") Integer id){
        QueryWrapper<Blog> wrapper=new QueryWrapper<>();
        //考虑到数据库主键id自增，如果中间有博客删除的话，根据id+1会找不到，所以使用原博客id列出大于id的，状态为激活的，升序，取第一条
        wrapper.lambda().eq(Blog::getStatus,"1")
                .gt(Blog::getId,id)
                .orderByAsc(Blog::getId)
                .last("limit 1");
        Blog blog = blogService.getOne(wrapper);

        ResultBean<Blog> resultBean=new ResultBean<>();
        //为防止下一篇博客不为空报错，则为空时不给其赋code=FAIL，直接赋值，前端有做判断

        resultBean.setData(blog);

        return resultBean;
    }


    @GetMapping("/selectPrevBlog")
    public ResultBean<Blog> selectPrevBlog(@RequestParam(value = "id") Integer id){
        QueryWrapper<Blog> wrapper=new QueryWrapper<>();
        //考虑到数据库主键id自增，如果中间有博客删除的话，根据id-1会找不到，所以使用原博客id列出小于于id的，状态为激活的，降序，取第一条
        wrapper.lambda().eq(Blog::getStatus,"1")
                .lt(Blog::getId,id)
                .orderByDesc(Blog::getId)
                .last("limit 1");
        Blog blog = blogService.getOne(wrapper);

        ResultBean<Blog> resultBean=new ResultBean<>();
        if(ObjectUtil.isNotEmpty(blog)){
            resultBean.setData(blog);
        }else {
            resultBean.setCode(ResultBean.FAIL);
        }
        return resultBean;
    }

    /**
     * 获取博客
     * @param blog
     * @param sort
     * @param page
     * @param pageSize
     * @return
     */
    @GetMapping("/selectGroupLikeBlogListByPage")
    @AccessLimit(second = 3,maxCount = 10)
    public ResultBean<IPage<Blog>> selectGroupLikeBlogListByPage(
            Blog blog,
            @RequestParam(value = "sort",defaultValue = "addTime")String sort,
            @RequestParam(value = "page",defaultValue = "1")Integer page,
            @RequestParam(value = "pageSize",defaultValue = "10")Integer pageSize){

        ResultBean<IPage<Blog>> resultBean=new ResultBean<>();
        QueryWrapper<Blog> blogQueryWrapper = designWrapper(blog, sort);
        blogQueryWrapper.select(Blog.class,i->!"content".equals(i.getColumn()));

        IPage<Blog> iPage=new Page<>();
        iPage.setCurrent(page);
        iPage.setSize(pageSize);

        IPage<Blog> blogIPage = blogService.page(iPage, blogQueryWrapper);
        //System.out.println("看一下分页.....");
        //System.out.println(blogIPage.getRecords());
        if(ObjectUtil.isNotEmpty(blogIPage.getRecords())){
            resultBean.setData(blogIPage);
        }else {
            resultBean.setCode(ResultBean.FAIL);
        }
        return resultBean;
    }


    /**
     * 获取博客类别及对应博客
     * @return
     */
    @GetMapping("/selectBlogByAllType")
    public ResultBean<Map<String,Object>> selectBlogAllType(){
        QueryWrapper<Blogtype> wrapper=new QueryWrapper<>();
        //获取博客类别，限制6个类别
        wrapper.lambda().last("limit 6");
        List<Blogtype> list = blogTypeService.list(wrapper);
        ResultBean<Map<String,Object>> resultBean=new ResultBean<>();
        if(list.size()==0){
            resultBean.setCode(ResultBean.FAIL);
            return resultBean;
        }
        //返回的内容集合
        Map<String,Object> map=new HashMap<>();
        for(Blogtype blogtype:list){
            QueryWrapper<Blog> blogQueryWrapper=new QueryWrapper<>();
            //根据类别和状态获取各类别对应博客，并按点击次数排序
            blogQueryWrapper.lambda().eq(Blog::getTypeId,blogtype.getId()).eq(Blog::getStatus,1).orderByDesc(Blog::getClickNum);
            //依旧是不需要具体内容
            blogQueryWrapper.select(Blog.class,i->!"content".equals(i.getColumn()));
            Page<Blog> page = blogService.page(new Page<>(1, 6), blogQueryWrapper);
            map.put(blogtype.getTypeName(),page);
        }
        resultBean.setData(map);
        return resultBean;
    }

    /**
     * 获取博客类别
     * @param data
     * @return
     */
    @PostMapping("/selectBlogType")
    public ResultBean<List<Blogtype>> selectBlogType(
            @RequestParam(value = "data",required = false) String data){
        Map<String,Object> map=new HashMap<>();
        if("all".equals(data)){
            map=null;
        }
        ResultBean<List<Blogtype>> resultBean=new ResultBean<>();
        List<Blogtype> blogtypes = blogTypeService.listByMap(map);
        if(blogtypes.size()==0){
            resultBean.setCode(ResultBean.FAIL);
        }else {
            resultBean.setData(blogtypes);
        }
        return resultBean;
    }

    /**
     * 制造QueryWrapper的工具方法
     * @param blog
     * @param sort
     * @return
     */
    public static QueryWrapper<Blog> designWrapper(Blog blog,String sort){
        QueryWrapper<Blog> wrapper=new QueryWrapper<>();
        //简介
        if(StrUtil.isNotBlank(blog.getIntroduction())){
            wrapper.lambda().like(Blog::getIntroduction,blog.getIntroduction());
        }
        //标题
        if(StrUtil.isNotBlank(blog.getTitle())){
            wrapper.lambda().like(Blog::getTitle,blog.getTitle());
        }
        //关键词
        if(StrUtil.isNotBlank(blog.getKeyword())){
            wrapper.lambda().like(Blog::getKeyword,blog.getKeyword());
        }
        //是否置顶
        if(blog.getIsTop()!=null){
            wrapper.lambda().eq(Blog::getIsTop,blog.getIsTop());
        }
        //是否推荐（加精）
        if(blog.getIsRecommend()!=null){
            wrapper.lambda().eq(Blog::getIsRecommend,blog.getIsRecommend());
        }
        //新增（入库）时间
        if(blog.getAddTime()!=null){
            wrapper.lambda().eq(Blog::getAddTime,blog.getAddTime());
        }
        //博客状态
        if(blog.getStatus()!=null){
            wrapper.lambda().eq(Blog::getStatus,blog.getStatus());
        }
        //博客类别id
        if(blog.getTypeId()!=null){
            wrapper.lambda().eq(Blog::getTypeId,blog.getTypeId());
        }

        //设置排序字段
        switch (sort){
            case "addTime":
                wrapper.lambda().orderByDesc(Blog::getAddTime);
                break;
            case "updateTime":
                wrapper.lambda().orderByDesc(Blog::getUpdateTime);
                break;
            case "clickNum":
                wrapper.lambda().orderByDesc(Blog::getClickNum);
                break;
        }
        wrapper.lambda().eq(Blog::getStatus,"1");

        return wrapper;
    }
}
